---
title: "語法對比與映射"
description: "學習 JavaScript 語法如何映射到 Kotlin 語法，包括變數、函數、控制結構和集合"
---

# 語法對比與映射

歡迎來到 JavaScript 到 Kotlin 轉換的第一個模組！在本模組中，我們將探索 JavaScript 語法如何映射到 Kotlin 語法，幫助你理解這兩種語言之間的基本差異和相似之處。

## 學習目標

通過本模組的學習，你將能夠：
- 理解 JavaScript 變數宣告如何映射到 Kotlin
- 將 JavaScript 函數轉換為 Kotlin 函數
- 將 JavaScript 控制結構映射到 Kotlin 等價結構
- 使用 Kotlin 的類型系統和空安全
- 有效使用 Kotlin 集合
- 應用 Kotlin 的簡潔語法模式

## 變數宣告和類型系統

### JavaScript 變數 vs Kotlin 變數

在 JavaScript 中，你使用 `let`、`const` 和 `var` 進行變數宣告。Kotlin 有更明確的類型系統，使用 `val`（不可變）和 `var`（可變）。

<UniversalEditor title="變數宣告對比" compare={true}>
```javascript !! js
// JavaScript 變數宣告
let name = "LangShift";
const age = 25;
var isActive = true;

// JavaScript 帶類型註解（TypeScript 風格）
let message: string = "Hello";
const count: number = 42;
```

```kotlin !! kt
// Kotlin 變數宣告
val name = "LangShift"  // 類型推斷為 String
var age = 25           // 類型推斷為 Int
val isActive = true    // 類型推斷為 Boolean

// Kotlin 顯式類型註解
val message: String = "Hello"
var count: Int = 42
```
</UniversalEditor>

### 主要差異

1. **不可變性**：Kotlin 中的 `val` 類似於 JavaScript 中的 `const`，但 `val` 可以在執行時賦值一次
2. **類型推斷**：Kotlin 可以推斷類型，但你也可以顯式指定它們
3. **空安全**：Kotlin 有內建的空安全，而 JavaScript 沒有

<UniversalEditor title="空安全對比" compare={true}>
```javascript !! js
// JavaScript - 沒有空安全
let user = null;
let name = user.name; // 執行時錯誤！

// JavaScript 可選鏈操作符
let name = user?.name; // 安全訪問
```

```kotlin !! kt
// Kotlin - 內建空安全
val user: String? = null
// val name = user.name // 編譯錯誤！

// Kotlin 安全調用操作符
val name = user?.name // 安全訪問，如果 user 為 null 則返回 null

// Kotlin 非空斷言
val name = user!!.name // 如果 user 為 null 則拋出異常
```
</UniversalEditor>

## 函數宣告

### JavaScript 函數 vs Kotlin 函數

JavaScript 有多種宣告函數的方式，而 Kotlin 有更一致的方法。

<UniversalEditor title="函數宣告對比" compare={true}>
```javascript !! js
// JavaScript 函數宣告
function greet(name) {
    return "Hello, " + name + "!";
}

// 箭頭函數
const greetArrow = (name) => {
    return "Hello, " + name + "!";
};

// 帶隱式返回的箭頭函數
const greetShort = name => "Hello, " + name + "!";

// 帶預設參數的函數
function greetWithDefault(name = "World") {
    return "Hello, " + name + "!";
}
```

```kotlin !! kt
// Kotlin 函數宣告
fun greet(name: String): String {
    return "Hello, $name!"
}

// Kotlin 表達式體函數
fun greetShort(name: String) = "Hello, $name!"

// Kotlin 帶預設參數的函數
fun greetWithDefault(name: String = "World"): String {
    return "Hello, $name!"
}

// Kotlin lambda 表達式
val greetLambda: (String) -> String = { name -> "Hello, $name!" }
```
</UniversalEditor>

### 函數重載

Kotlin 支援函數重載，而 JavaScript 沒有原生支援。

<UniversalEditor title="函數重載" compare={true}>
```javascript !! js
// JavaScript - 沒有原生重載
function add(a, b) {
    if (typeof a === 'string' && typeof b === 'string') {
        return a + b;
    }
    return a + b;
}

// 不同簽名需要不同方法
function addNumbers(a, b) {
    return a + b;
}

function addStrings(a, b) {
    return a + b;
}
```

```kotlin !! kt
// Kotlin 函數重載
fun add(a: Int, b: Int): Int {
    return a + b
}

fun add(a: String, b: String): String {
    return a + b
}

fun add(a: Double, b: Double): Double {
    return a + b
}

// 使用
val result1 = add(5, 3)        // 調用 Int 版本
val result2 = add("Hello", "World") // 調用 String 版本
val result3 = add(3.14, 2.86)  // 調用 Double 版本
```
</UniversalEditor>

## 控制結構

### If 語句

兩種語言都有相似的 if 語句，但 Kotlin 的 if 是表達式。

<UniversalEditor title="If 語句對比" compare={true}>
```javascript !! js
// JavaScript if 語句
let age = 18;
let status;

if (age >= 18) {
    status = "adult";
} else {
    status = "minor";
}

// JavaScript 三元操作符
let status2 = age >= 18 ? "adult" : "minor";
```

```kotlin !! kt
// Kotlin if 表達式
val age = 18
val status = if (age >= 18) {
    "adult"
} else {
    "minor"
}

// Kotlin if 作為表達式（不需要三元操作符）
val status2 = if (age >= 18) "adult" else "minor"
```
</UniversalEditor>

### When 表達式（Kotlin）vs Switch 語句（JavaScript）

Kotlin 的 `when` 比 JavaScript 的 `switch` 更強大。

<UniversalEditor title="When vs Switch 對比" compare={true}>
```javascript !! js
// JavaScript switch 語句
let day = "Monday";
let message;

switch (day) {
    case "Monday":
        message = "Start of work week";
        break;
    case "Friday":
        message = "TGIF!";
        break;
    default:
        message = "Regular day";
}

// JavaScript 帶貫穿
switch (day) {
    case "Monday":
    case "Tuesday":
    case "Wednesday":
    case "Thursday":
    case "Friday":
        message = "Work day";
        break;
    default:
        message = "Weekend";
}
```

```kotlin !! kt
// Kotlin when 表達式
val day = "Monday"
val message = when (day) {
    "Monday" -> "Start of work week"
    "Friday" -> "TGIF!"
    else -> "Regular day"
}

// Kotlin when 帶多個條件
val message2 = when (day) {
    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Work day"
    else -> "Weekend"
}

// Kotlin when 帶範圍
val number = 5
val result = when (number) {
    in 1..5 -> "Small number"
    in 6..10 -> "Medium number"
    else -> "Large number"
}
```
</UniversalEditor>

### 迴圈

Kotlin 的迴圈語法比 JavaScript 更簡潔。

<UniversalEditor title="迴圈對比" compare={true}>
```javascript !! js
// JavaScript for 迴圈
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// JavaScript for...of 迴圈
const items = ["apple", "banana", "orange"];
for (const item of items) {
    console.log(item);
}

// JavaScript forEach
items.forEach(item => console.log(item));

// JavaScript while 迴圈
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}
```

```kotlin !! kt
// Kotlin for 迴圈
for (i in 0..4) {
    println(i)
}

// Kotlin for 帶範圍
for (i in 0 until 5) {
    println(i)
}

// Kotlin for 帶步長
for (i in 0..10 step 2) {
    println(i)
}

// Kotlin for 帶集合
val items = listOf("apple", "banana", "orange")
for (item in items) {
    println(item)
}

// Kotlin forEach
items.forEach { item -> println(item) }

// Kotlin while 迴圈
var count = 0
while (count < 5) {
    println(count)
    count++
}
```
</UniversalEditor>

## 集合

### 陣列和列表

JavaScript 陣列更靈活，而 Kotlin 有不同類型的集合用於不同用例。

<UniversalEditor title="集合對比" compare={true}>
```javascript !! js
// JavaScript 陣列
let numbers = [1, 2, 3, 4, 5];
let fruits = ["apple", "banana"];

// 添加元素
numbers.push(6);
fruits.push("orange");

// 刪除元素
numbers.pop();
fruits.splice(1, 1);

// 陣列方法
let doubled = numbers.map(x => x * 2);
let evenNumbers = numbers.filter(x => x % 2 === 0);
let sum = numbers.reduce((acc, x) => acc + x, 0);

// 陣列解構
let [first, second, ...rest] = numbers;
```

```kotlin !! kt
// Kotlin 列表
val numbers = listOf(1, 2, 3, 4, 5)
val fruits = mutableListOf("apple", "banana")

// 添加元素（可變列表）
fruits.add("orange")

// 刪除元素
fruits.removeAt(1)

// 列表操作
val doubled = numbers.map { it * 2 }
val evenNumbers = numbers.filter { it % 2 == 0 }
val sum = numbers.reduce { acc, x -> acc + x }

// 列表解構
val (first, second, *rest) = numbers

// Kotlin 陣列
val numberArray = arrayOf(1, 2, 3, 4, 5)
val stringArray = arrayOf("hello", "world")
```
</UniversalEditor>

### 映射和物件

JavaScript 物件類似於 Kotlin 映射，但語法不同。

<UniversalEditor title="映射和物件對比" compare={true}>
```javascript !! js
// JavaScript 物件
let person = {
    name: "John",
    age: 30,
    city: "New York"
};

// 訪問屬性
console.log(person.name);
console.log(person["age"]);

// 添加屬性
person.job = "Developer";

// 物件解構
let { name, age } = person;

// JavaScript Map
let userMap = new Map();
userMap.set("id", 1);
userMap.set("name", "Alice");
userMap.set("email", "alice@example.com");

console.log(userMap.get("name"));
```

```kotlin !! kt
// Kotlin 映射
val person = mapOf(
    "name" to "John",
    "age" to 30,
    "city" to "New York"
)

// 訪問值
println(person["name"])
println(person["age"])

// 可變映射
val mutablePerson = mutableMapOf(
    "name" to "John",
    "age" to 30
)

// 添加條目
mutablePerson["job"] = "Developer"

// 映射解構
for ((key, value) in person) {
    println("$key: $value")
}

// Kotlin 資料類（比映射更適合結構化資料）
data class Person(
    val name: String,
    val age: Int,
    val city: String
)

val john = Person("John", 30, "New York")
println(john.name)
```
</UniversalEditor>

## 字串模板和插值

Kotlin 的字串模板比 JavaScript 的模板字面量更強大。

<UniversalEditor title="字串模板對比" compare={true}>
```javascript !! js
// JavaScript 模板字面量
let name = "World";
let greeting = `Hello, ${name}!`;

// JavaScript 帶表達式
let a = 5;
let b = 3;
let result = `Sum: ${a + b}`;

// JavaScript 帶函數調用
function getGreeting(name) {
    return `Hello, ${name}!`;
}

let message = getGreeting("Alice");
```

```kotlin !! kt
// Kotlin 字串模板
val name = "World"
val greeting = "Hello, $name!"

// Kotlin 帶表達式
val a = 5
val b = 3
val result = "Sum: ${a + b}"

// Kotlin 帶函數調用
fun getGreeting(name: String) = "Hello, $name!"

val message = getGreeting("Alice")

// Kotlin 帶複雜表達式
val items = listOf("apple", "banana", "orange")
val itemList = "Items: ${items.joinToString(", ")}"
```
</UniversalEditor>

## 練習題目

### 練習 1：將 JavaScript 函數轉換為 Kotlin

將這個 JavaScript 函數轉換為 Kotlin：

```javascript
function calculateTotal(items) {
    let total = 0;
    for (let item of items) {
        total += item.price * item.quantity;
    }
    return total;
}
```

<UniversalEditor title="練習 1 解答" compare={true}>
```javascript !! js
function calculateTotal(items) {
    let total = 0;
    for (let item of items) {
        total += item.price * item.quantity;
    }
    return total;
}

// 使用
const items = [
    { name: "Apple", price: 1.50, quantity: 3 },
    { name: "Banana", price: 0.75, quantity: 2 }
];
console.log(calculateTotal(items));
```

```kotlin !! kt
fun calculateTotal(items: List<Item>): Double {
    var total = 0.0
    for (item in items) {
        total += item.price * item.quantity
    }
    return total
}

// 資料類用於結構化資料
data class Item(
    val name: String,
    val price: Double,
    val quantity: Int
)

// 使用
val items = listOf(
    Item("Apple", 1.50, 3),
    Item("Banana", 0.75, 2)
)
println(calculateTotal(items))
```
</UniversalEditor>

### 練習 2：將 JavaScript 陣列操作轉換為 Kotlin

將這些 JavaScript 陣列操作轉換為 Kotlin：

```javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenSquares = numbers
    .filter(n => n % 2 === 0)
    .map(n => n * n)
    .reduce((sum, n) => sum + n, 0);
```

<UniversalEditor title="練習 2 解答" compare={true}>
```javascript !! js
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenSquares = numbers
    .filter(n => n % 2 === 0)
    .map(n => n * n)
    .reduce((sum, n) => sum + n, 0);

console.log(evenSquares); // 220
```

```kotlin !! kt
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenSquares = numbers
    .filter { it % 2 == 0 }
    .map { it * it }
    .reduce { sum, n -> sum + n }

println(evenSquares) // 220
```
</UniversalEditor>

## 關鍵要點

1. **類型安全**：Kotlin 提供編譯時類型檢查，而 JavaScript 是動態類型
2. **空安全**：Kotlin 的空安全在編譯時防止空指標異常
3. **不可變性**：使用 `val` 表示不可變變數，`var` 表示可變變數
4. **表達式化**：Kotlin 的 `if` 和 `when` 是表達式，不僅僅是語句
5. **集合**：Kotlin 有不同類型的集合用於不同用例
6. **字串模板**：Kotlin 的字串插值比 JavaScript 的更強大
7. **函數重載**：Kotlin 支援函數重載，JavaScript 不支援

## 下一步

在下一個模組中，我們將探索 JVM 生態系統和工具鏈，包括：
- 理解 JVM 平台
- 使用 Gradle 建置系統
- 套件管理和依賴
- IDE 整合和除錯工具

這個語法對比的基礎將幫助你理解如何有效地將 JavaScript 知識轉換為 Kotlin。 